package controllers;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import models.Event;
import models.OpenTokArchive;
import models.OpenTokSession;
import models.User;
import play.Routes;
import play.data.Form;
import play.mvc.Controller;
import play.mvc.Http.Session;
import play.mvc.Result;
import providers.MyUsernamePasswordAuthProvider;
import providers.MyUsernamePasswordAuthProvider.MyLogin;
import providers.MyUsernamePasswordAuthProvider.MySignup;
import views.html.index;
import views.html.login;
import views.html.profile;
import views.html.restricted;
import views.html.signup;
import be.objectify.deadbolt.actions.Restrict;

import com.feth.play.module.pa.PlayAuthenticate;
import com.feth.play.module.pa.providers.password.UsernamePasswordAuthProvider;
import com.opentok.api.OpenTokSDK;
import com.opentok.api.constants.RoleConstants;

public class Application extends Controller {

	public static final String FLASH_MESSAGE_KEY = "message";
	public static final String FLASH_ERROR_KEY = "error";
	public static final String USER_ROLE = "user";

	public static Result index() {
		return ok(index.render());
	}

	public static User getLocalUser(final Session session) {
		final User localUser = User.findByAuthUserIdentity(PlayAuthenticate
				.getUser(session));
		return localUser;
	}

	@Restrict(Application.USER_ROLE)
	public static Result restricted() {
		final User localUser = getLocalUser(session());
		return ok(restricted.render(localUser));
	}

	@Restrict(Application.USER_ROLE)
	public static Result profile() {
		
		final User localUser = getLocalUser(session());
		return ok(profile.render(localUser));
	}

	public static Result login() {
		return ok(login.render(MyUsernamePasswordAuthProvider.LOGIN_FORM));
	}

	public static Result doLogin() {
		com.feth.play.module.pa.controllers.Authenticate.noCache(response());
		final Form<MyLogin> filledForm = MyUsernamePasswordAuthProvider.LOGIN_FORM
				.bindFromRequest();
		if (filledForm.hasErrors()) {
			// User did not fill everything properly
			return badRequest(login.render(filledForm));
		} else {
			// Everything was filled
			return UsernamePasswordAuthProvider.handleLogin(ctx());
		}
	}

	public static Result signup() {
		return ok(signup.render(MyUsernamePasswordAuthProvider.SIGNUP_FORM));
	}

	public static Result jsRoutes() {
		return ok(
				Routes.javascriptRouter("jsRoutes",
						controllers.routes.javascript.Signup.forgotPassword()))
				.as("text/javascript");
	}

	public static Result doSignup() {
		com.feth.play.module.pa.controllers.Authenticate.noCache(response());
		final Form<MySignup> filledForm = MyUsernamePasswordAuthProvider.SIGNUP_FORM
				.bindFromRequest();
		if (filledForm.hasErrors()) {
			// User did not fill everything properly
			return badRequest(signup.render(filledForm));
		} else {
			// Everything was filled
			// do something with your part of the form before handling the user
			// signup
			return UsernamePasswordAuthProvider.handleSignup(ctx());
		}
	}

	public static String formatTimestamp(final long t) {
		return new SimpleDateFormat("yyyy-dd-MM HH:mm:ss").format(new Date(t));
	}
	
	public static Result sessionPublisher(Long eventId){
		return ok(views.html.videoSessionPublisher.render(eventId));
	}
	
	public static Result sessionSubscriber(Long eventId){
		return ok(views.html.videoSessionSubscriber.render(eventId)); 	
	}
	
	public static Result startSession(Long eventId){
		OpenTokSDK openTokSDK = new OpenTokSDK(21313161, "2c819ea062cc6557e618a4de655bcdce9e33d4f4");
		OpenTokSession openTokSession = new OpenTokSession();
		try {
			String sessionId = openTokSDK.create_session().session_id;
			openTokSession.sessionId  = sessionId;
			String token = openTokSDK.generate_token(sessionId);
			openTokSession.token = token;
			Event event = new Event();;
			event.id = eventId;
			openTokSession.event = event;
			//openTokSession.event.id = eventId;//Event.findByEventId(eventId);;
			openTokSession.apiKey = 21313161;
			openTokSession.status = "session_started";
			openTokSession.moderatorToken = openTokSDK.generate_token(sessionId, RoleConstants.MODERATOR);
			openTokSession.subscriberToken = openTokSDK.generate_token(sessionId, RoleConstants.SUBSCRIBER);
			openTokSession.publisherToken = openTokSDK.generate_token(sessionId, RoleConstants.PUBLISHER);
			openTokSession.save();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ok(play.libs.Json.toJson(openTokSession));
	}
	
	public static Result checkSessionStarted(Long eventId){
		OpenTokSession openTokSession = OpenTokSession.findByEventId(eventId);
		if(openTokSession != null && !openTokSession.status.equals("session_stopped")){
			openTokSession.apiKey = 21313161;
			return ok(play.libs.Json.toJson(openTokSession));
		}
		return ok(play.libs.Json.toJson("invalid_event"));
	}
	
	public static Result checkToTeachOrLearn(Long eventId){
		User user = getLocalUser(session());
		OpenTokSession openTokSession = OpenTokSession.findByEventId(eventId);
		if(openTokSession != null && openTokSession.status.equals("session_stopped")){
			return ok(login.render(MyUsernamePasswordAuthProvider.LOGIN_FORM));
		}
		Event event = Event.findByEventId(eventId);
		if(event != null){
			if(event.user.id == user.id ){
				return redirect(controllers.routes.Application.sessionPublisher(eventId));
			}else{
				return redirect(controllers.routes.Application.sessionSubscriber(eventId));
			}
		}else{
			return ok(login.render(MyUsernamePasswordAuthProvider.LOGIN_FORM));
		}
	}
	
	public static Result disconnectSession(Long eventId){
		OpenTokSession openTokSession = OpenTokSession.findByEventId(eventId);
		openTokSession.status = "session_stopped";
		openTokSession.update();
		return redirect(controllers.routes.Calendar.list());
	}
	
	public static Result saveArchive(Long sessionId, String archiveId){
		OpenTokArchive archive = new OpenTokArchive();
		OpenTokSession openTokSession = OpenTokSession.findById(sessionId);
		Event event = Event.findByEventId(openTokSession.event.id);
		
		if(event != null){
			archive.eventName = openTokSession.event.title;
			archive.event = openTokSession.event;
		}
		
		archive.archiveId = archiveId;
		archive.openTokSession = openTokSession;
		archive.status = "open";
		archive.save();
		return redirect(controllers.routes.Calendar.list());
	}
	
	public static Result renderLoadArchive(Long eventId){
		OpenTokArchive openTokArchive = OpenTokArchive.findByEventId(eventId);
		return ok(views.html.videoSessionArchiver.render(openTokArchive));
	}
	
	public static Result renderArchivedVideosList(){
		List<OpenTokArchive> openTokArchives = OpenTokArchive.fetchAllByStatus("closed");
        return ok(views.html.archivelist.render(openTokArchives));
	}
	
	public static Result updateArchiveStatus(String archiveId, String status){
		 OpenTokArchive openTokArchive = OpenTokArchive.findByArchiveId(archiveId);
		if(openTokArchive != null){
			openTokArchive.status = status;
			openTokArchive.update();
		}
		return ok("Success");
	}

}